package net.zigin.nhi.could.waste.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import net.zigin.commons.util.*;
import net.zigin.nhi.could.waste.aop.LoginAspect;
import net.zigin.nhi.could.waste.dao.SysRoleMapper;
import net.zigin.nhi.could.waste.model.*;
import net.zigin.nhi.could.waste.service.SysRoleService;
import net.zigin.nhi.could.waste.service.SysUserService;
import net.zigin.nhi.could.waste.util.ExcelUtil;
import net.zigin.nhi.could.waste.vo.DeviceBaseVo;
import net.zigin.nhi.could.waste.vo.TokenInfoBo;
import net.zigin.nhi.could.waste.constants.CommonConstants;
import net.zigin.nhi.could.waste.dao.SysUserHospitalMapper;
import net.zigin.nhi.could.waste.dto.HospitalDepartDto;
import net.zigin.nhi.could.waste.exception.EpiCloudException;
import net.zigin.nhi.could.waste.util.CodeUtil;
import net.zigin.nhi.could.waste.util.EncryptDataUtil;
import net.zigin.nhi.could.waste.vo.HospitalDepartVo;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.zigin.nhi.could.waste.dao.BaseMapper;
import net.zigin.nhi.could.waste.dao.HospitalDepartMapper;
import net.zigin.nhi.could.waste.service.HospitalDepartService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/*#################################################################*
# 说明:以下代码通过哲勤代码生成工具自动生成    
# 工具:GeneratorCode
# 作者:mgw1986                                                  
# 生成时间:2021-9-8 0:01:01                                               
##################################################################*/


/**
 * HospitalDepart服务实现类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: HospitalDepartServiceImpl
 * @date 2021-9-8 0:01:01
 */
@Service
public class HospitalDepartServiceImpl extends AbstractServiceImpl<HospitalDepart, String> implements HospitalDepartService {
    @Autowired
    private HospitalDepartMapper hospitalDepartMapper;
    @Autowired
    private SysUserHospitalMapper sysUserHospitalMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;

    @Override
    public BaseMapper<HospitalDepart, String> getMapper() {
        return hospitalDepartMapper;
    }

    /**
     * 新建科室负责人
     */
    private void initDepartAdmin(HospitalDepartDto hospitalDepartDto) {
        sysUserService.checkMobileExist(hospitalDepartDto.getMobile());
        SysUser sysUser = new SysUser(hospitalDepartDto);
        sysUserService.insert(sysUser);
        SysUserHospital sysUserHospital = new SysUserHospital(hospitalDepartDto);
        sysUserHospital.setSysUserId(sysUser.getId());
        sysUserHospital.setHospitalBaseId(hospitalDepartDto.getHospitalBaseId());
        sysUserHospital.setHospitalDepartId(hospitalDepartDto.getId());
        sysUserHospitalMapper.insert(sysUserHospital);
        sysRoleService.concatUser(sysUser.getId(), 2);
        hospitalDepartDto.setUserStaffId(sysUserHospital.getId());
    }

    private void initDepartAdmin(HospitalDepartVo hospitalDepartDto) {
        String userStaffId = sysUserService.checkMobileExistReturnUserStaffId(hospitalDepartDto.getMobile());
        if (!StringUtil.isNullOrEmpty(userStaffId)) {
            hospitalDepartDto.setUserStaffId(userStaffId);
            return;
        }
        SysUser sysUser = new SysUser(hospitalDepartDto);
        sysUserService.insert(sysUser);
        SysUserHospital sysUserHospital = new SysUserHospital(hospitalDepartDto);
        sysUserHospital.setSysUserId(sysUser.getId());
        sysUserHospital.setHospitalBaseId(hospitalDepartDto.getHospitalBaseId());
        sysUserHospital.setHospitalDepartId(hospitalDepartDto.getId());
        sysUserHospitalMapper.insert(sysUserHospital);
        sysRoleService.concatUser(sysUser.getId(), 2);
        hospitalDepartDto.setUserStaffId(sysUserHospital.getId());
    }

    @Override
    public String saveOrUpdate(HospitalDepartDto hospitalDepartDto) {
        AssertUtil.isNull(hospitalDepartDto, "科室信息不能为空！");
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        // 获取医院id
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        hospitalDepartDto.setHospitalBaseId(hospitalBaseId);
        hospitalDepartDto.setPinyinName(PinYinUtil.getPingYin(hospitalDepartDto.getName()));
        //验证科室名称是否重复
        AssertUtil.isNull(judgeHospitalDepartName(hospitalDepartDto,hospitalBaseId),"科室名称不能重复!");
        if (StringUtil.isNullOrEmpty(hospitalDepartDto.getId())) {
            // todo 其他信息校验
            hospitalDepartDto.setId(StringUtil.get32UUID());
            //initDepartAdmin(hospitalDepartDto);
            hospitalDepartDto.setCreateTime(new Date());
            hospitalDepartDto.setModifyTime(new Date());
            hospitalDepartDto.setCreateUser(tokenInfo.getLoginName());
            HospitalDepart hospitalDepart = ReflectUtil.copyProperties(hospitalDepartDto, HospitalDepart.class);
            hospitalDepartMapper.insert(hospitalDepart);
            return hospitalDepart.getId();
        }
        //取消创建科室负责人
        /*if (!StringUtil.isNullOrEmpty(hospitalDepartDto.getUserStaffName())) {
            String staffId = sysUserHospitalMapper.getIdByName(hospitalDepartDto.getUserStaffName(), hospitalBaseId);
            if (StringUtil.isNullOrEmpty(staffId)) {
                initDepartAdmin(hospitalDepartDto);
                staffId = sysUserHospitalMapper.getIdByName(hospitalDepartDto.getUserStaffName(), hospitalBaseId);
            }
            if (!staffId.equals(hospitalDepartDto.getUserStaffId())) {
                // 移除之前科室负责人的角色
                SysUserHospital sysUserHospital = sysUserHospitalMapper.selectByPrimaryKey(hospitalDepartDto.getUserStaffId());
                sysRoleMapper.removeUser(sysUserHospital.getSysUserId());
            }
        }*/
        hospitalDepartDto.setModifyTime(new Date());
        hospitalDepartDto.setModifyUser(tokenInfo.getLoginName());
        HospitalDepart hospitalDepart = ReflectUtil.copyProperties(hospitalDepartDto, HospitalDepart.class);
        hospitalDepartMapper.updateByPrimaryKeySelective(hospitalDepart);
        return hospitalDepart.getId();
    }

    private boolean judgeHospitalDepartName(HospitalDepartDto hospitalDepartDto,String hospitalBaseId) {
        AssertUtil.isNull(hospitalDepartDto.getName(),"科室名称不能为空");
        String id = hospitalDepartDto.getId();
        Map<String,Object> paramsMap = ParamsMapUtil.getInstance()
                .addParam("id",id)
                .addParam("name",hospitalDepartDto.getName())
                .addParam("hospitalBaseId",hospitalBaseId);
        Integer integer = hospitalDepartMapper.judgeExistDepartName(paramsMap);
        return integer > 0;
    }

    @Override
    public List<HospitalDepartVo> getList(HospitalDepartDto hospitalDepartDto) {
        Map<String, Object> paramMap = getDepartParam(hospitalDepartDto);
        return hospitalDepartMapper.getInfoListByCondition(paramMap);
    }

    @Override
    public Integer getCount(HospitalDepartDto hospitalDepartDto) {
        Map<String, Object> paramMap = getDepartParam(hospitalDepartDto);
        return hospitalDepartMapper.selectCount(paramMap);
    }

    private Map<String, Object> getDepartParam(HospitalDepartDto hospitalDepartDto) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        hospitalDepartDto.setHospitalBaseId(hospitalBaseId);
        return ParamsMapUtil.getInstance()
                .addParam("hospitalBaseId", hospitalDepartDto.getHospitalBaseId())
                .addParam("name", hospitalDepartDto.getName())
                .addParam("code", hospitalDepartDto.getCode())
                .addParam("mobile", hospitalDepartDto.getMobile())
                .addParam("type", hospitalDepartDto.getType())
                .addParam("pageIndex", hospitalDepartDto.getPageIndex())
                .addParam("pageSize", hospitalDepartDto.getPageSize());
    }

    @Override
    public void generateQrCode(String id, HttpServletResponse response) {
        HospitalDepart hospitalDepart = hospitalDepartMapper.selectByPrimaryKey(id);
        if (hospitalDepart == null) {
            throw new EpiCloudException("科室不存在");
        }
        String encryptData = EncryptDataUtil.encryptData(CommonConstants.QRCODE_HOSPITAL_DEPART, hospitalDepart.getId());
        CodeUtil.encodeQrcode(hospitalDepart.getName(), encryptData, response);
    }

    @Override
    public HospitalDepartVo getInfoById(String id) {
        return hospitalDepartMapper.getInfoById(id);
    }

    @Override
    public void exportList(HospitalDepartDto hospitalDepartDto, HttpServletResponse response) {
        List<HospitalDepartVo> list = hospitalDepartMapper.getListByIds(hospitalDepartDto.getId());
        try {
            // 不带标题
            ExcelUtil.exportExcel(list, HospitalDepartVo.class, "科室信息", new ExportParams(), response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public void importList(MultipartFile file) {
        TokenInfoBo tokenInfo = LoginAspect.getTokenInfo();
        String hospitalBaseId = sysUserHospitalMapper.getHospitalBaseIdBySysUserId(tokenInfo.getUserId());
        try {
            List<HospitalDepartVo> hospitalDepartVos = ExcelUtil.importExcel(file, 0, 1, HospitalDepartVo.class);
            // 新建 todo 科室类型 名称 编码 电话 医院（通过登录人获取）负责人  创建时间 创建人 科室备注
            hospitalDepartVos.forEach(hospitalDepartVo -> {
                HospitalDepartDto hospitalDepartDto = ReflectUtil.copyProperties(hospitalDepartVo, HospitalDepartDto.class);
                //验证科室名称是否重复
                AssertUtil.isNull(judgeHospitalDepartName(hospitalDepartDto,hospitalBaseId),"科室名称不能重复!");
                HospitalDepart hospitalDepart = ReflectUtil.copyProperties(hospitalDepartVo, HospitalDepart.class);
                hospitalDepart.setId(StringUtil.get32UUID());
                hospitalDepart.setCreateTime(new Date());
                hospitalDepart.setCreateUser(tokenInfo.getLoginName());
                hospitalDepart.setHospitalBaseId(hospitalBaseId);
                hospitalDepartVo.setId(hospitalDepart.getId());
                // todo 科室电话 负责人
                if (!StringUtil.isNullOrEmpty(hospitalDepartVo.getMobile()) && !StringUtil.isNullOrEmpty(hospitalDepartVo.getUserStaffName())) {
                    initDepartAdmin(hospitalDepartVo);
                    hospitalDepart.setUserStaffId(hospitalDepartVo.getUserStaffId());
                }
                hospitalDepartMapper.insert(hospitalDepart);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载模板(下拉选项)
     */
    @Override
    public void downloadTemplate(HttpServletResponse response) {
        try {
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), HospitalDepartDto.class, new ArrayList<>());
            //给单位类型设置下拉选项
            ExcelUtil.selectList(workbook,0,0,0,new String[]{"科室","分院"});
            ExcelUtil.downLoadExcel("科室信息",response,workbook);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void downloadTemplate2(HttpServletResponse response) {
        try {
            ExcelUtil.defaultExport(new ArrayList<>(), HospitalDepartVo.class, "科室信息", response, new ExportParams(), new ArrayList<>());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void generateQrCode(List<String> ids, HttpServletResponse response) {
        List<Map<String, String>> encryptDataList = new ArrayList<>();
        for (String id : ids) {
            HospitalDepart hospitalDepart = hospitalDepartMapper.selectByPrimaryKey(id);
            Map<String, String> map = new HashMap<>();
            map.put("name", hospitalDepart.getName());
            map.put("content", EncryptDataUtil.encryptData(CommonConstants.QRCODE_HOSPITAL_DEPART, id));
            encryptDataList.add(map);
        }
        CodeUtil.getCodeZip(response, encryptDataList);
    }

    @Override
    public void fillPinYinName() {
        List<HospitalDepart> hospitalDeparts = hospitalDepartMapper.selectAllList();
        hospitalDeparts.forEach(hospitalDepart -> {
            hospitalDepart.setPinyinName(PinYinUtil.getPinYinHeadChar(hospitalDepart.getName()));
            hospitalDepartMapper.updateByPrimaryKeySelective(hospitalDepart);
        });
    }

    @Override
    public Boolean judgeRemove(String id) {
        // 存在下级科室 或者科室下有人员
        Integer childrenCount = hospitalDepartMapper.judgeExistChildren(id);
        Integer staffCount = hospitalDepartMapper.judgeExistStaff(id);
        return (childrenCount + staffCount) > 0;
    }
}